package be.groept.ace.enquete.servlets;

import java.io.IOException;
import java.util.ArrayList;
import java.util.SortedSet;
import java.util.TreeSet;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.log4j.Logger;

import be.groept.ace.enquete.beans.Link;
import be.groept.ace.enquete.model.beans.Survey;
import be.groept.ace.enquete.model.beans.User;
import be.groept.ace.enquete.model.dao.DAOCommand;
import be.groept.ace.enquete.model.dao.DAOFactory;
import be.groept.ace.enquete.model.dao.DAOManager;
import be.groept.ace.enquete.model.exceptions.DAOException;
import be.groept.ace.enquete.utils.ServletUtils;

/**
 * Servlet implementation class UserHomeServlet
 */
public abstract class UserServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
	private static Logger logger = Logger.getLogger(UserServlet.class);

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		request.setAttribute("permission", "user");
		request.setAttribute("errors", new ArrayList<String>());
		addNavigationLinks(request, response);
		setHeader(request, "header");
		int returncode = handleGet(request, response);
		switch (returncode) {
			case 302:
				//redirect
				response.sendRedirect(response.encodeRedirectURL((String) request.getAttribute("redirect")));
				break;
			case 404:
				response.sendError(404);
				break;
			case 200:
			default:
				if(isForm(request)) {
					ServletUtils.gotoFormTemplatePage(request, response);
				} else {
					ServletUtils.gotoTemplatePage(request, response);
				}		
				break;
		}
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		request.setAttribute("permission", "user");
		request.setAttribute("errors", new ArrayList<String>());
		addNavigationLinks(request, response);
		setHeader(request, "header");
		int returncode = handlePost(request, response);
		switch (returncode) {
			case 302:
				//redirect
				response.sendRedirect(response.encodeRedirectURL((String) request.getAttribute("redirect")));
				break;
			case 404:
				response.sendError(404);
				break;
			case 200:
			default:
				if(isForm(request)) {
					ServletUtils.gotoFormTemplatePage(request, response);
				} else {
					ServletUtils.gotoTemplatePage(request, response);
				}		
				break;
		}
	}
	
	private void addNavigationLinks(HttpServletRequest request, HttpServletResponse response) throws ServletException  {
		HttpSession session = request.getSession(false);
		final User currentUser = (User)session.getAttribute("user");
		DAOManager daoManager = null;
		try {
			daoManager  = (new DAOFactory()).createDAOManager(DAOFactory.PERSISTENCEMODE.MYSQL);
		} catch (DAOException daoe) {
			logger.fatal(daoe.toString());
			throw new ServletException(daoe.getMessage() + "\nPlease configure the resource in the META_INF/context.xml file");
		}
		
		try {
			@SuppressWarnings("unchecked")
			SortedSet<Survey> surveys = (SortedSet<Survey>)daoManager.transactionAndClose(new DAOCommand() {
				@Override
				public Object execute(DAOManager daoManager) throws DAOException {
					return daoManager.getSurveyDAO().findAllSurveysForUser(currentUser);
				}
			});
			
			for (Survey survey : surveys) {
				addNavigationLink(request, survey.getId(), survey.getTitle(), response.encodeURL(request.getContextPath() + "/user/enquete?id=" + survey.getId()));
			}
		} catch (DAOException daoe) {
			logger.error(daoe.toString());
		}
		
		
		
	}
	
	protected void addNavigationLink(HttpServletRequest request, int order, String name, String link) {
		@SuppressWarnings("unchecked")
		SortedSet<Link> links = (SortedSet<Link>)request.getAttribute("navigationLinks");
		if (links == null) {
			links = new TreeSet<Link>();
			request.setAttribute("navigationLinks", links);
		}
		links.add(new Link(order, name, link));
	}
	
	protected void setHeader(HttpServletRequest request, String header) {
		request.setAttribute("headerPage", header);
	}
	
	protected void addHeaderLink(HttpServletRequest request, int order, String name, String link) {
		@SuppressWarnings("unchecked")
		SortedSet<Link> links = (SortedSet<Link>)request.getAttribute("headerLinks");
		if (links == null) {
			links = new TreeSet<Link>();
			request.setAttribute("headerLinks", links);
		}
		links.add(new Link(order, name, link));
	}
	
	protected void setFormActionUrl(HttpServletRequest request, String formActionUrl) {
		request.setAttribute("formActionUrl", formActionUrl);
	}
	
	protected void setTitle(HttpServletRequest request, String title) {
		request.setAttribute("title", title);
	}
	
	protected void setPage(HttpServletRequest request, String page) {
		request.setAttribute("content", page);
	}
	
	protected void setHeaderSelectedLink(HttpServletRequest request, int order) {
		@SuppressWarnings("unchecked")
		SortedSet<Link> links = (SortedSet<Link>)request.getAttribute("headerLinks");
		setSelectedLink(links, order);
	}
	
	protected void setNavigationSelectedLink(HttpServletRequest request, int order) {
		@SuppressWarnings("unchecked")
		SortedSet<Link> links = (SortedSet<Link>)request.getAttribute("navigationLinks");
		setSelectedLink(links, order);
	}
	
	private void setSelectedLink(SortedSet<Link> set, int order) {
		for(Link l : set) {
			if (l.getOrderNumber() == order) {
				l.setSelected(true);
			} else {
				l.setSelected(false);
			}
		}
	}
	
	protected boolean isForm(HttpServletRequest request) {
		return (boolean)request.getAttribute("form");
	}
	
	protected void setForm(HttpServletRequest request, boolean form) {
		request.setAttribute("form", form);
	}
	
	protected abstract int handleGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException;
	protected abstract int handlePost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException;

}
